#include "audio.h"
#include "Arduino.h"
#include <WiFi.h>
#include "stdio.h"
#include <driver/i2s.h>
#include "esp_timer.h"
#include <driver/adc.h>
#include "stft.h"
    

#include "tensorflow/lite/micro/all_ops_resolver.h"
#include "tensorflow/lite/micro/micro_error_reporter.h"
#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/schema/schema_generated.h"
#include "./tools/kiss_fftr.h"


#define I2S_WS 32
#define I2S_SD 35
#define I2S_SCK 33
#define I2S_PORT I2S_NUM_0
#define bufferLen 512  // 增加缓冲区大小以适应更多音频数据


#define ringBufSize 1024*24
//环形缓冲区
int16_t* ringBuf=NULL;


void i2s_install();
void i2s_setpin();

extern kiss_fftr_cfg kfft_cfg;
extern int tensorFlowRunState;
extern float*tensorInput;

size_t bytesIn = 0;

void mycopy(int16_t*dist,int16_t*src,int size){
  for(int i=0;i<size;i++){
    dist[i]=src[i];
  }
}

static int ringBufIndex=0;

int getRingIndex(){
  return ringBufIndex;
}
int getRingMax(){
  return ringBufSize;
}

int getRingData(int16_t*point,int index,int size){
  if(ringBuf==NULL){
    return 0;
  }
  int temp=0;
  for(int i=0;i<size;i++){
    temp=index+i;
    //超过界限了，从头开始
    if(temp>=ringBufSize){
      temp=temp-ringBufSize;
    }else if(temp<0){
      temp=temp+ringBufSize;
    }
    point[i]=ringBuf[temp];
  }
  return 1;
}

// stft((uint16_t*)(sBuffer+i*128),out+countRecord*129,kfft_cfg);
//将数据复制到环形缓冲区中

void task1(void *pvParameters) {
  TickType_t xLastWakeTime = 0; // 初始化上次唤醒时间为0
	const TickType_t xDelay = 20 / portTICK_PERIOD_MS; // 延迟1秒   
  Serial.println("test3");
  //long ttm=micros();
  while(1){
     esp_err_t result = i2s_read(I2S_PORT,ringBuf+ringBufIndex, bufferLen * sizeof(int16_t), &bytesIn, portMAX_DELAY);
     if (result == ESP_OK && bytesIn > 0) {
        ringBufIndex+=bufferLen;
        if(ringBufIndex>=ringBufSize){
          ringBufIndex=0;
        }
        //Serial.printf("time:%d\r\n",micros()-ttm);
        //ttm=micros();
    }
    vTaskDelayUntil(&xLastWakeTime, xDelay);
  }

}


void startAudio(){
    Serial.println("test1");
    i2s_install();
    i2s_setpin();
    i2s_start(I2S_PORT);
    Serial.println("test2");
    ringBuf=(int16_t*)malloc(ringBufSize*sizeof(int16_t));
    memset(ringBuf,0,ringBufSize*sizeof(int16_t));
    if(ringBuf==NULL){
      Serial.println("buffer init error!");
      return;
    }
    xTaskCreate(task1,"test",1024*4, NULL, configMAX_PRIORITIES-1, NULL);
    

    
}



void i2s_install() {
    const i2s_config_t i2s_config = {
        .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
        .sample_rate = 16000,
        .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
        .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
        .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_STAND_I2S),
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
        .dma_buf_count = 4,
        .dma_buf_len = bufferLen,
        .use_apll = false
    };

    i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
}

void i2s_setpin() {
    const i2s_pin_config_t pin_config = {
        .bck_io_num = I2S_SCK,
        .ws_io_num = I2S_WS,
        .data_out_num = I2S_PIN_NO_CHANGE,
        .data_in_num = I2S_SD
    };

    i2s_set_pin(I2S_PORT, &pin_config);
}